/**
 * @原理
 * 在一个函数的作用域中使用自由变量，自由变量往上一级作用域中寻找，若找到，引用上一级的变量，使得上一级作用域的这个变量不能被垃圾回收机制回收。
 * @一般形式
 * 在一个函数中，接受一个函数为参数或return一个函数
 * @使用场景
 *  */
// 几乎同时设置5个定时器
/* for (var i = 0; i < 5; i++) {
    setTimeout(() => {
        console.log(new Date(), i)
    }, 1000)
}
console.log(new Date(), i)
setTimeout(() => {
    console.log("------")
}, 1000)

for (var i = 0; i < 5; i++) {
    (function (j) {
        setTimeout(() => {
            console.log(new Date(), j)
        }, 1000)
    })(i)
}
console.log(new Date(), i)

for (var i = 0; i < 5; i++) {
    (function seconConsole(j){
        setTimeout(()=>{
            console.log(j)
        },1000*j)
    })(i)
} */

let p = Promise.resolve()
for (let i = 0; i < 5; i++) {
    p = p.then(() =>
        new Promise(resolve => {
            setTimeout(() => {
                console.log(i)
                resolve()
            }, 1000)
        })
    )
}

const tasks = []; // 这里存放异步操作的 Promise
const output = (i) => new Promise((resolve) => {
    setTimeout(() => {
        console.log(new Date, i);
        resolve();
    }, 1000 * i);
});

// 生成全部的异步操作
for (var i = 0; i < 5; i++) {
    tasks.push(output(i));
}

// 异步操作完成之后，输出最后的 i
Promise.all(tasks).then(() => {
    setTimeout(() => {
        console.log(new Date, i);
    }, 1000);
});



// 模拟其他语言中的 sleep，实际上可以是任何异步操作
const sleep = (timeountMS) => new Promise((resolve) => {
    setTimeout(resolve, timeountMS);
});

/* (async () => {  // 声明即执行的 async 函数表达式
    for (var i = 0; i < 5; i++) {
        await sleep(1000);
        console.log(new Date, i);
    }

    await sleep(1000);
    console.log(new Date, i);
})(); */

/* var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}
 */
var test = function () {
    var arr = []
    for (var i = 0; i < 5; i++) {
        arr.push(function () {
            return i * i
        })
    }
    return arr
}

var test1 = test()
console.log(test1[0]())
console.log(test1[1]())
console.log(test1[2]())

/* 封装私有变量 */
function f1() { var sum = 0; var obj = { inc: function () { sum++; return sum; } }; return obj; } let result = f1(); console.log(result.inc());//1console.log(result.inc());//2console.log(result.inc());//3

let url = "https://github.com/daily-interview/fe-interview/*&&哈哈哈"
console.log("url",url)
console.log(decodeURI(url))
console.log(decodeURIComponent(url))

var uri="my test.asp?name=ståle&car=saab";
document.write(encodeURI(uri)+ "<br>");
document.write(decodeURI(uri));